/*****************************************************************************/
/*                                                                           */
/* Copyright notice: please read file license.txt in the NetBee root folder. */
/*                                                                           */
/*****************************************************************************/

#pragma once


#include <stdio.h>
#include <list>

/*! \addtogroup NetBeePacketEngine
	\{
*/

#define nbNETPFLCOMPILER_DEBUG_DETAIL_LEVEL 0 /* It may be 0, 1 or 2 */							//!< Requested debug level in the PDF compiler
#define nbNETPFLCOMPILER_DEBUG_PROTOGRAH_DUMP_FILENAME			"debug_proto_graph.dot"			//!< Default name for a debug file containing the NetPDL protocol graph (i.e., encapsulations)
#define nbNETPFLCOMPILER_DEBUG_FILTERAUTOMATON_DUMP_FILENAME	"debug_filter_automaton.dot"	//!< Default name for a debug file containing the automaton representing the NetPFL filter
#define nbNETPFLCOMPILER_DEBUG_HIR_CODE_FILENAME				"debug_hir_code.asm"			//!< Default name for a debug file
#define nbNETPFLCOMPILER_DEBUG_LIR_NOOPT_GRAPH_FILENAME 		"debug_mir_no_opt_graph.dot"	//!< Default name for a debug file
#define nbNETPFLCOMPILER_DEBUG_LIR_CODE_FILENAME				"debug_mir_code.asm"			//!< Default name for a debug file
#define nbNETPFLCOMPILER_DEBUG_LIR_GRAPH_FILENAME				"debug_mir_graph.dot"			//!< Default name for a debug file
#define nbNETPFLCOMPILER_DEBUG_NO_CODE_GRAPH_FILENAME			"debug_no_code_graph.dot"		//!< Default name for a debug file
#define nbNETPFLCOMPILER_DEBUG_NETIL_GRAPH_FILENAME				"debug_netil_graph.dot"			//!< Default name for a debug file
#define nbNETPFLCOMPILER_DEBUG_NETIL_CODE_FILENAME				"debug_netil_code.asm"			//!< Default name for a debug file containing the generated NetIL file
#define nbNETPFLCOMPILER_DEBUG_ASSEMBLY_CODE_FILENAME			"debug_assembly_code.asm"		//!< Default name for a debug file containing the generated assembly code (in case of JIT compilation)

#define nbNETPFLCOMPILER_MAX_MESSAGE 1024		 //!< Maximum length for an error or warning message generated by the compiler


/*!
	\brief Types of Field Descriptors supported in this module

	The format of the field descriptor (_nbExtractedFieldsDescriptor) depends on which field(s) the
	user is interested in. For instance, if the user wants to extract a single field that may
	appear only once in the packet, we use a first data format. If the field may be repeated,
	we have to use another data format, and so on.
	The values of this enumerator are used to tell the final user about the format of the
	data read from the NetVM instance.
*/
typedef enum nbExtractedFieldsDataFormat_t
{
	nbNETPFLCOMPILER_DATAFORMAT_FIELD,		//!< We can have a single instance of a single field		
//	nbNETPFLCOMPILER_DATAFORMAT_REFERENCE,
//	nbNETPFLCOMPILER_DATAFORMAT_PROTOCOL,
	nbNETPFLCOMPILER_DATAFORMAT_FIELDLIST,	//!< We can return several fields, and their number is not know a priori (i.e. we use the 'allfields' keyword)
//	nbNETPFLCOMPILER_DATAFORMAT_PROTOLIST,
	nbNETPFLCOMPILER_DATAFORMAT_MULTIPROTO,	//!< We can have multiple protocol instances, so a field can appear several times in different headers
	nbNETPFLCOMPILER_DATAFORMAT_MULTIFIELD,	//!< We can have multiple instances of the same field within the same header
	nbNETPFLCOMPILER_DATAFORMAT_NO_KIND		//!< Unspecified type (used as sentinel)
} nbExtractedFieldsDataFormat_t;


//! Types of NetPDL fields supported in this module
typedef enum nbExtractedFieldsFieldType_t
{
	PDL_FIELD_TYPE_FIXED,			//!< Fixed-length field
	PDL_FIELD_TYPE_VARLEN,			//!< Variable length field
	PDL_FIELD_TYPE_BIT,				//!< Bitfield
	PDL_FIELD_TYPE_PADDING,			//!< Padding field
	PDL_FIELD_TYPE_TOKEND,			//!< Token-ended field
	PDL_FIELD_TYPE_TOKWRAP,			//!< Token-wrapped field
	PDL_FIELD_TYPE_LINE,			//!< Line field
	PDL_FIELD_TYPE_PATTERN,			//!< Pattern field
	PDL_FIELD_TYPE_EATALL,			//!< Eatall field
	PDL_FIELD_TYPE_ALLFIELDS,		//!< Special token for 'allfields' field extraction keyword
	PDL_FIELD_TYPE_INVALID_TYPE		//!< This value is used only as a sentinel, in order to avoid invalid field types
} nbExtractedFieldsFieldType_t;


// Forward declarations
//struct _nbExtractedFieldsDescriptorVector;


/*!
	\brief This structure holds an error or warning message generated by the compiler.

	In case of multiple errors, this structure can store all these messages in a list.
*/
struct _nbNetPFLCompilerMessages
{
	char	MessageString[nbNETPFLCOMPILER_MAX_MESSAGE];	//!< The message string
	struct	_nbNetPFLCompilerMessages *Next;				//!< Pointer to the next message of the list
};




/*!
	\brief This structure contains all the information related to a field that is extracted from a packet.

	This structure can be used to parse the result of the NetVM code when dealing with extracted fields,
	in order to get the values of those fields in the current packet.
	Additionally, this structure contains some more information such as field names, and more.
*/

using namespace std;

struct _nbExtractedFieldsDescriptor
{
	//nbExtractedFieldsDataFormat_t DataFormatType;	//!< Type of field descriptor, according to the types supported in \ref nbExtractedFieldsDataFormat_t
	//const char* Name;								//!< Protocol field name
	//const char* Proto;								//!< Protocol name
	//nbExtractedFieldsFieldType_t FieldType;			//!< Field type, according to the types supported in \ref nbExtractedFieldsFieldType_t
	int Offset;										//!< Field offset
	int Length;										//!< Field length
	uint32_t BitField_Value;						//!< Field value (only for bitfields)							
	_nbExtractedFieldsDescriptor *DVct;		//!< Pointer to a _nbExtractedFieldsDescriptorVector
	bool Valid;										//!< 'true' if the field has been found in the current packet
	void* UserExtension;							//!< Void pointer; can be used to associate some info to the field from user space	
	int num_entries;
	//uint32_t	Position;							//!< Position of the current fields within the info partition
	
	_nbExtractedFieldsDescriptor():
	/*DataFormatType(nbNETPFLCOMPILER_DATAFORMAT_NO_KIND), Name(0), Proto(0), FieldType(PDL_FIELD_TYPE_INVALID_TYPE), */Offset(0), Length(0), BitField_Value(0), DVct(0), Valid(false), UserExtension(NULL), num_entries(0)/*, Position(0)*/{}
};

struct _nbExtractFieldInfo
{
	nbExtractedFieldsDataFormat_t DataFormatType;	//!< Type of field descriptor, according to the types supported in \ref nbExtractedFieldsDataFormat_t
	const char* Name;								//!< Protocol field name
	const char* Proto;								//!< Protocol name
	nbExtractedFieldsFieldType_t FieldType;			//!< Field type, according to the types supported in \ref nbExtractedFieldsFieldType_t
	_nbExtractFieldInfo():
	DataFormatType(nbNETPFLCOMPILER_DATAFORMAT_NO_KIND), Name(0), Proto(0), FieldType(PDL_FIELD_TYPE_INVALID_TYPE){}
};


/*!	
	\brief This structure contains an array of _nbExtractedFieldsDescriptor
*/
/*struct _nbExtractedFieldsDescriptorVector
{
	_nbExtractedFieldsDescriptor *FieldDescriptor;	//!< Array of _nbExtractedFieldsDescriptor
	int NumEntries;							//!< Number of entries in the array

	//! Standard constructor
	_nbExtractedFieldsDescriptorVector(int Size):NumEntries(Size)
		{
			FieldDescriptor= new _nbExtractedFieldsDescriptor[Size];
		}
	~_nbExtractedFieldsDescriptorVector()
		{
			delete []FieldDescriptor;
		}

	//! Update the current vector with a new vector (created elsewhere)
	void SetVector(_nbExtractedFieldsDescriptor *NewFieldDescriptor)
		{
			FieldDescriptor= NewFieldDescriptor;
		}

	//! Copy the content of another vector (created elsewhere) into the current one
	_nbExtractedFieldsDescriptorVector *copy()
		{	
			_nbExtractedFieldsDescriptorVector * NewDescriptorVector= new _nbExtractedFieldsDescriptorVector(NumEntries);
			NewDescriptorVector->SetVector(FieldDescriptor);
			return NewDescriptorVector;
		}
};*/


/*!
	\}
*/
